﻿/*
 * ShpConnection.SpatialSchema
 * 
 * initial implementation : 12.12.2008
 *
 * Copyright (c) Adam Sida, asida@centrum.cz.
 * All rights reserved.
 * 
 * for license see Petra.Gis.License.txt
 */
using System;
using System.IO;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using Petra.Gis.DataServices;

namespace Petra.Gis.DataServices.SHP
{


  public partial class ShpConnection : SpatialDbConnection
  {


    /// <summary>
    /// returns following data table structure:
    /// FEATURE_CATALOG,FEATURE_SCHEMA, FEATURE_NAME, FEATURE_TYPE, TITLE, 
    /// ABSTRACT, AUTHORITY, BOUNDS, CONTACTINFO, KEYWORDS
    /// </summary>
    protected override DataTable getFeaturesInfo(string[] rowFilterArray)
    {

      string filter = "";

      if (rowFilterArray != null)
        filter = createFeatureInfoFilter(rowFilterArray);

      // prepare table
      DataTable tab = new DataTable("Features");
      prepareCol(tab, "FEATURE_CATALOG", typeof(string));
      prepareCol(tab, "FEATURE_SCHEMA", typeof(string));
      prepareCol(tab, "FEATURE_NAME", typeof(string));
      prepareCol(tab, "FEATURE_TYPE", typeof(string));
      prepareCol(tab, "TITLE", typeof(string));
      prepareCol(tab, "ABSTRACT", typeof(string));
      prepareCol(tab, "AUTHORITY", typeof(string));
      prepareCol(tab, "BOUNDS", typeof(string));
      prepareCol(tab, "CONTACTINFO", typeof(string));
      prepareCol(tab, "KEYWORDS", typeof(string));


      // go over all shps
      foreach (KeyValuePair<string, string> shp in _shps)
      {
        //ShpBinaryReader shpBinaryReader = new ShpBinaryReader(new FileStream(shp.Value, FileMode.Open, FileAccess.Read), DataEndian.BigIndian);
        BinaryReader shpBinaryReader = new BinaryReader(new FileStream(shp.Value, FileMode.Open, FileAccess.Read));
        ShapefileHeader mainHeader = ShapefileHeader.Read(shpBinaryReader);
        if (mainHeader.ShapeType != ShapeGeometryTypes.NullShape)
          tab.Rows.Add(shp.Value, null, shp.Key, "BASE TABLE", "", "", "", mainHeader.Bounds, "", "");

        shpBinaryReader.Close();
      }

      return filterOutput(tab, filter);

    }




    /// <summary>
    /// returns following data table structure:
    /// FEATURE_CATALOG, FEATURE_SCHEMA, FEATURE_NAME, FIELD_NAME, TITLE, 
    /// DOMAIN_GEOMETRY_TYPE, COORDINATESYSTEM_ID.
    /// where COORDINATESYSTEM_ID is data source depended (non standard) value
    /// see table COORDINATE_SYSTEMS
    /// </summary>
    protected override DataTable getFieldsInfo(string[] rowFilterArray)
    {

      string filter = "";

      if (rowFilterArray != null)
        filter = createFieldsInfoFilter(rowFilterArray);


      DataTable tab = new DataTable("Fields");
      prepareCol(tab, "FEATURE_CATALOG", typeof(string));
      prepareCol(tab, "FEATURE_SCHEMA", typeof(string));
      prepareCol(tab, "FEATURE_NAME", typeof(string));
      prepareCol(tab, "FIELD_NAME", typeof(string));
      prepareCol(tab, "TITLE", typeof(string));
      prepareCol(tab, "DOMAIN_GEOMETRY_TYPE", typeof(int));
      prepareCol(tab, "COORDINATESYSTEM_ID", typeof(string));

      foreach (KeyValuePair<string, string> shp in _shps)
      {
        BinaryReader shpBinaryReader = new BinaryReader(new FileStream(shp.Value, FileMode.Open, FileAccess.Read));
        ShapefileHeader mainHeader = ShapefileHeader.Read(shpBinaryReader);
        if (mainHeader.ShapeType != ShapeGeometryTypes.NullShape)
          tab.Rows.Add(shp.Value, null, shp.Key, "SHPGeometry", "", mainHeader.ShapeType, "CS1");
        shpBinaryReader.Close();
      }

      return filterOutput(tab, filter);


    }





    /// <summary>
    /// returns following data table structure:
    /// COORDINATESYSTEM_ID, COORDINATESYSTEM_INFO 
    /// where COORDINATESYSTEM_ID is data source depended (non standard) value
    /// </summary>
    protected override DataTable getCsInfo(string[] rowFilterArray)
    {

      string filter = "";

      if (rowFilterArray != null)
        filter = createCoordSystemInfoFilter(rowFilterArray);

      DataTable tab = new DataTable("FeatureCSBaseInfo");
      prepareCol(tab, "COORDINATESYSTEM_ID", typeof(string));
      prepareCol(tab, "COORDINATESYSTEM_INFO", typeof(string));

      tab.Rows.Add("CS1", "Authority = " + _csAuthority + "; Code=" + _csCode + "; StorageUnits = " + _csUnits);

      return filterOutput(tab, filter);

    }




    /// <summary>
    /// returns following data table structure:
    /// FEATURE_CATALOG,FEATURE_SCHEMA, FEATURE_NAME, FIELD_NAME, SPATIAL_INDEX_TYPE
    /// where spatial index type is string with value (none, gdosql_bounds, gdosql_tile)
    /// </summary>
    protected override DataTable getSpatialIndexInfo(string[] rowFilterArray)
    {
      string filter = "";

      if (rowFilterArray != null)
        filter = createSpatialIndexInfoFilter(rowFilterArray);

      DataTable tab = new DataTable("FeatureSpatialIndexesInfo");
      prepareCol(tab, "FEATURE_CATALOG", typeof(string));
      prepareCol(tab, "FEATURE_SCHEMA", typeof(string));
      prepareCol(tab, "FEATURE_NAME", typeof(string));
      prepareCol(tab, "FIELD_NAME", typeof(string));
      prepareCol(tab, "SPATIAL_INDEX_TYPE", typeof(string));

      foreach (KeyValuePair<string, string> shp in _shps)
      {
        if(!File.Exists(Path.GetFileNameWithoutExtension(shp.Value)))
          tab.Rows.Add(shp.Value, null, shp.Key, "SHPGeometry", SpatialIndexType.None);
        else
          tab.Rows.Add(shp.Value, null, shp.Key, "SHPGeometry", SpatialIndexType.QuadTreeIndex);
      }

      return filterOutput(tab, filter);
    }




    /// <summary>
    /// returns following data table structure:
    /// FEATURE_CATALOG,FEATURE_SCHEMA, FEATURE_NAME, FIELD_NAME, TILE_FIELD_NAME, TILE_FN_NAME
    /// where spatial index type is string with value (none, gdosql_bounds, gdosql_tile)
    /// </summary>
    protected override DataTable getTileSpatialIndexInfo(string[] rowFilterArray)
    {

      throw new NotSupportedException();    


    }





    protected override DataTable getQtreeSpatialIndexInfo(string[] tableRowFilter)
    {
      throw new NotImplementedException();
    }





    private void prepareCol(DataTable tab, string colName, System.Type colType)
    {
      DataColumn col = new DataColumn();

      col.DataType = colType;
      col.ColumnName = colName;
      tab.Columns.Add(col);
    }





    private DataTable filterOutput(DataTable inputTab, string filter)
    {

      

      if (filter != "")
      {
        DataTable outTab = inputTab.Clone();
        foreach (DataRow dr in inputTab.Select(filter))
          outTab.ImportRow(dr);

        return outTab;
      }
      else
        return inputTab;

      

    }




  }
}
